
#ifndef _Input_H_
#define _Input_H_

#include "../Utils/Vector2D.h"
#include "../Utils/Util.h"

#include <set>
#include <vector>
#include <map>
#include <string>
#include <SDL/SDL.h>
#include <functional>

#include "Checker.h"

class Input {
  public:

    static Input& instance();

    void updateKey(SDLKey key, bool down);
    void updateMouseButton(int b, bool down);
    void clearKey(const std::string key);
    //void updateMouse(...);

    bool isKeyDownAndClear(const std::string key);
    bool isKeyDown(const std::string key);
    bool isKeyDown(SDLKey key) const;

    bool isButtonDown(int b) const;

    bool registerBinding(const std::string task, const std::string key);
    void addBinding(const std::string task, Checker* c);
    bool registerBinding(const std::string key, std::vector<std::string> tasks);
    bool registerBindings(std::map<std::string, std::string> mapping);

    std::vector<SDLKey> getAllDownKeys(void) const;
    Vector2D getMousePosition(bool ortho=false) const;
    
  private:
    
    std::set<SDLKey> down_keys;
    std::set<int> down_buttons;
    std::map<std::string, std::vector<Checker*>*> key_bindings;
    Vector2D mouse_pos;
    int screen_height;
    int screen_width;


    bool isMouseKey(const std::string);
    bool Input::any(std::vector<Checker*>* checks, bool clear=false);

    // Private constructors since this is a singleton
    Input();
    Input(const Input&);
    Input& operator=(const Input&);
    ~Input();

};

#endif

